<script setup lang='tsx'>
import { ProForm, ProButton } from 'tdesign-pro-component';
import { getRoleList, createRole, deleteRole, getRole, updateRole, getMenuIdsByRoleId, saveRoleMenu } from '@/api/role';
import { getMenuChildren } from '@/api/menu';
import useFormModal from '@/hooks/useFormModal';
import { ref, onMounted } from 'vue';
import { MessagePlugin } from 'tdesign-vue-next';
import { useColor } from '@/hooks';

const {ROLE_MENU_HEADER_COLOR} = useColor();

const currentId = ref<NullAble<number>>(null);

const roleIndex = ref<NullAble<number>>(null);

const nameZh = ref('');

const roleList = ref<Role[]>([]);

const menuChildren = ref<MenuWithChildren[]>([]);

const currentMenuList = ref<number[]>([])

onMounted(() => {
    search();
    getMenuChildren(1).then(res => {
        menuChildren.value = res;
    })
})

function search() {
    getRoleList({ nameZh: nameZh.value }).then(res => {
        roleList.value = res;
    })
}

const [createOpen] = useFormModal<Role>(ProForm, {
    options: [
        {
            name: 'name',
            label: '名称',
            span: 12,
            formItemProps: {
                labelAlign: 'top'
            },
            rules: [{ required: true }]
        },
        {
            name: 'nameZh',
            label: '中文名称',
            span: 12,
            formItemProps: {
                labelAlign: 'top'
            },
            rules: [{ required: true }]
        }
    ],
    request: () => Promise.resolve(null),
    onSubmit: (data) => {
        createRole(data).then(() => {
            search();
        })
    }
}, {
    header: '新增角色'
});

const [updateOpen] = useFormModal<Role>(ProForm, {
    options: [
        {
            name: 'id',
            label: '编号',
            span: 12,
            disabled: true,
            formItemProps: {
                labelAlign: 'top'
            },
        },
        {
            name: 'name',
            label: '名称',
            span: 12,
            formItemProps: {
                labelAlign: 'top'
            },
            rules: [{ required: true }]
        },
        {
            name: 'nameZh',
            label: '中文名称',
            span: 12,
            formItemProps: {
                labelAlign: 'top'
            },
            rules: [{ required: true }]
        }
    ],
    request: () => getRole(currentId.value!),
    onSubmit: (data) => {
        updateRole({ ...data, id: currentId.value! }).then(() => {
            tableRef.value?.reset();
            currentId.value = null;
        })
    }
}, {
    header: '新增角色'
})

function handleDeleteRole(id: number) {
    // TODO: 删除角色
    deleteRole(id).then(() => {
        search();
    })
}

function handleShowUpdate(id: number) {
    currentId.value = id;
    updateOpen();
}

function buttonChange(state: boolean, id: number, parent: MenuWithChildren) {
    if (roleIndex.value === null) {
        MessagePlugin.warning('请选择一个角色');
        return;
    }
    const arr = currentMenuList.value;
    if (state) {
        arr.push(...[parent.value, id]);
    } else {
        arr.splice(arr.indexOf(id), 1);
        const flag = arr.some(item => parent.children!.map(item => item.value).includes(item));
        if (!flag) {
            arr.splice(arr.indexOf(parent.value), 1);
        }
    }

    currentMenuList.value = Array.from(new Set(arr));
}

function handleMenuChange(state: boolean, current: MenuWithChildren, parent: MenuWithChildren) {
    if (roleIndex.value === null) {
        MessagePlugin.warning('请选择一个角色');
        return;
    }
    let arr = currentMenuList.value;
    if (state) {
        arr.push(...[current.value, parent.value]);
        if (current.children) {
            arr.push(...(current.children!.map(item => item.value)))
        }
    } else {
        arr.splice(arr.indexOf(current.value), 1);
        const flag = arr.some(item => parent.children!.map(item => item.value).includes(item));
        if (current.children) {
            arr = arr.filter(item => !current.children!.map(item => item.value).includes(item))
        }
        if (!flag) {
            arr.splice(arr.indexOf(parent.value), 1);
        }
    }
    currentMenuList.value = Array.from(new Set(arr));
}

function isChecked(current: MenuWithChildren) {
    const flag = currentMenuList.value.includes(current.value);
    if (current.children) {
        return (flag && current.children!.every(item => currentMenuList.value.includes(item.value)))
    } else {
        return flag;
    }
}

function handleRoleClick(id: number) {
    getMenuIdsByRoleId(id).then(res => {
        roleIndex.value = id;
        currentMenuList.value = res;
    })
}

function handleSaveRoleMenu() {
    if(!roleIndex.value) {
        MessagePlugin.warning('请选择一个角色');
        return;
    }

    saveRoleMenu({ roleId: roleIndex.value!, menuIds: currentMenuList.value }).then(() => {
        MessagePlugin.success('保存成功')
    })
}

</script>

<template>
    <div>
        <div class="grid grid-cols-12 gap-x-8">
            <div class="col-span-3 bg-[var(--td-bg-color-container)]">
                <div class="grid grid-cols-5 gap-x-4 p-6">
                    <div class="col-span-4">
                        <t-input v-model="nameZh" placeholder="请输入名称"></t-input>
                    </div>
                    <div>
                        <t-button variant="outline" @click="search">查询</t-button>
                    </div>

                </div>
                <div class="flex items-center justify-between px-4 mb-3">
                    <div>
                        角色列表
                    </div>
                    <t-button size="small" variant="outline" @click="createOpen">
                        创建角色
                    </t-button>
                </div>
                <div class=" relative">
                    <t-list :split="true">
                        <t-list-item v-for="role, index in roleList" :key="role.id"
                            :style="index === 0 ? 'border-top: 1px solid var(--td-border-level-1-color)' : ''">
                            <span @click="() => handleRoleClick(role.id)"
                                :class="roleIndex === role.id ? 'text-[var(--td-brand-color)] cursor-pointer' : ' cursor-pointer'">
                                {{ role.nameZh }}
                            </span>
                            <template #action>
                                <t-button @click="handleShowUpdate(role.id)" variant="text" shape="square">
                                    <t-icon color="primary" style="color: var(--td-brand-color)" name="edit" />
                                </t-button>
                                <ProButton @confirm="handleDeleteRole(role.id)"
                                    :button-props="{ variant: 'text', shape: 'square' }">
                                    <template #content>
                                        <span>你正在执行删除操作，确认是否删除【{{ role.nameZh }}】角色？</span>
                                    </template>
                                    <t-icon color="primary" style="color: var(--td-brand-color)" name="delete" />
                                </ProButton>
                            </template>
                        </t-list-item>
                    </t-list>
                </div>
            </div>
            <div class="col-span-9">
                <t-card :bordered="false" style="border-radius: 0">
                    <template #header>
                        <div class="flex items-center">
                            <div class="w-1 bg-[var(--td-brand-color)] h-4 mr-2">

                            </div>
                            <div class="text-base">
                                角色权限设置
                            </div>
                        </div>
                    </template>
                    <div class="menu-container ">
                        <t-collapse size="small" :borderless="true">
                            <t-collapse-panel v-for="menu in menuChildren" :key="menu.value" :value="menu.value"
                                :header="menu.label">
                                <template #header>
                                    <div class="text-base font-normal">
                                        {{ menu.label }}
                                    </div>
                                </template>
                                <template v-if="menu.children">
                                    <div class="side-menu-container">
                                        <t-collapse size="small" :borderless="true">
                                            <t-collapse-panel v-for="sideMenu in menu.children" :key="sideMenu.value">
                                                <template #header>
                                                    <div class="font-normal">
                                                        <span>{{ sideMenu.label }}</span>
                                                    </div>
                                                </template>
                                                <template #headerRightContent>
                                                    <span><t-checkbox
                                                            @change="(state) => handleMenuChange(state, sideMenu, menu)"
                                                            :checked="isChecked(sideMenu)"
                                                            :value="sideMenu.value">全选</t-checkbox></span>
                                                </template>
                                                <template v-if="sideMenu.children">
                                                    <div class="grid grid-cols-6">
                                                        <div v-for="button in sideMenu.children" :key="button.value"
                                                            class="font-normal">
                                                            <t-checkbox
                                                                :checked="currentMenuList.includes(button.value)"
                                                                @change="(state) => buttonChange(state, button.value, sideMenu)"
                                                                lue="button.value"> {{ button.label }}</t-checkbox>
                                                        </div>
                                                    </div>
                                                </template>
                                            </t-collapse-panel>
                                        </t-collapse>
                                    </div>
                                </template>
                            </t-collapse-panel>
                        </t-collapse>
                    </div>
                    <div class="grid grid-cols-12 gap-4 mt-6">
                        <div class="col-span-10"></div>
                        <t-button @click="currentMenuList = []" theme="default">重置</t-button>
                        <t-button @click="handleSaveRoleMenu" :disabled="roleIndex === null">
                            保存
                        </t-button>
                    </div>
                </t-card>
            </div>
        </div>
    </div>
</template>

<style lang='scss' scoped>
.menu-container ::v-deep .t-collapse {
    background-color: v-bind('ROLE_MENU_HEADER_COLOR') !important;
}

.side-menu-container ::v-deep .t-collapse {
    background-color: transparent !important;
}
</style>